﻿using System;
using System.Security.Principal;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using MaxStoreErp.Core.Commands;
using MaxStoreErp.Core.Interfaces;
using MaxStoreErp.Core.Security;
using MaxStoreErp.Core.Ui.MainMenu;
using MaxStoreShop.Core.Contracts;
using MaxStoreShop.Core.Helpers;
using MaxStoreShop.Core.Services;
using MaxStoreShop.CoreModule.Settings;
using MaxStoreShop.CoreModule.Users;
using MaxStoreShop.Dal;
using MaxStoreShop.Dal.Repositories.Directories;
using MaxStoreShop.Logic.RepositoriesContracts.Directories;
using MaxStoreShop.Logic.Services.Directories;
using MaxStoreShop.Logic.ServicesContracts.Directories;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Unity;

namespace MaxStoreShop.CoreModule
{
    [Module(ModuleName = "MaxStoreShop.CoreModule")]
    public class CoreModule : MaxStoreErp.Core.BaseClasses.ModuleBase
    {
        public CoreModule()
        {
            AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
            AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
            Dispatcher.CurrentDispatcher.UnhandledException += CurrentDispatcherOnUnhandledException;
            Application.Current.DispatcherUnhandledException += CurrentOnDispatcherUnhandledException;
            TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
        }

        void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs unobservedTaskExceptionEventArgs)
        {
            ExceptionHandler(unobservedTaskExceptionEventArgs.Exception.Message);
        }

        void CurrentOnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs dispatcherUnhandledExceptionEventArgs)
        {
            ExceptionHandler(dispatcherUnhandledExceptionEventArgs.Exception.Message);
            dispatcherUnhandledExceptionEventArgs.Handled = true;
        }

        void CurrentDispatcherOnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs dispatcherUnhandledExceptionEventArgs)
        {
            ExceptionHandler(dispatcherUnhandledExceptionEventArgs.Exception.Message);
            dispatcherUnhandledExceptionEventArgs.Handled = true;
        }

        void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
        {
            var exception = (Exception)unhandledExceptionEventArgs.ExceptionObject;
            if (exception == null)
                return;

            ExceptionHandler(exception.Message);
        }

        protected override string ModuleName
        {
            get { return "Системный модуль"; }
        }

        protected override void RegisterServices()
        {
            base.RegisterServices();
            UnityContainer.RegisterInstance(typeof (ISettings), UnityContainer.Resolve<UserXmlSettings>());
            UnityContainer.RegisterInstance(typeof (ShopContext),
                new ShopContext(GetConnectionString()));
            UnityContainer.RegisterType<IUserRepository, UserRepository>()
                .RegisterType<IUserService, UserService>()
                .RegisterType<IUserLogin, Login.LoginPresenter>()
                .RegisterType<IPhotoHelper, PhotoHelper>();
        }

        protected override void RegisterMenuItems()
        {
            base.RegisterMenuItems();
            var icons = new ResourceDictionary
            {
                Source = new Uri("/MaxStoreShop.CoreModule;component/Resources/Images.xaml", UriKind.RelativeOrAbsolute)
            };
            MainMenuService.Add(new MenuItemControl
            {
                TileCaption = "Общие",
                GroupName = "Настройки",
                IsTileVisible = PermissionHelper.IsAdmin(),
                IconData = icons["SettingsIcon"] as Geometry,
                Command =
                    new RelayCommand(() => UnityContainer.Resolve<IDocumentManager>().NavigateTo<SettingsPresenter>())
            });
            MainMenuService.Add(new MenuItemControl
            {
                TileCaption = "Пользователи",
                GroupName = "Настройки",
                IsTileVisible = PermissionHelper.IsAdmin(),
                IconData = icons["UsersIcon"] as Geometry,
                Command = new RelayCommand(()=>UnityContainer.Resolve<IDocumentManager>().NavigateTo<UsersPresenter>())
            });
        }

        string GetConnectionString()
        {
            var settings = UnityContainer.Resolve<ISettings>();
            settings.LoadSettings();
            return settings.ConnectionString;
        }

        void ExceptionHandler(string message)
        {
            UnityContainer.Resolve<ILogger>().LogError(message);
            UnityContainer.Resolve<IMessager>()
                .InfoMessageAsync(message, "Ошибка выполнения операции");
        }
    }
}
